package com.vavr.checkincms.service;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.vavr.checkincms.common.constant.CommonConstants;
import com.vavr.checkincms.common.exception.BaseException;
import com.vavr.checkincms.common.util.HttpUtil;
import com.vavr.checkincms.configuration.CheckinProperties;
import com.vavr.checkincms.configuration.WechatProperties;
import com.vavr.checkincms.domain.data.MeetingParticipantDO;
import com.vavr.checkincms.domain.dto.CheckinUserDTO;
import com.vavr.checkincms.mapper.MeetingParticipantMapper;
import com.vavr.checkincms.util.CheckinRequestUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.stereotype.Service;

import static com.vavr.checkincms.common.domain.ResultEnum.LOGIN_ERROR;

/**
 * CheckinServiceImpl
 *
 * @since 2024.08
 */
@Slf4j
@Service
public class WechatLoginServiceImpl implements WechatLoginService {
    /**
     * 签到时间相关配置
     */
    private final WechatProperties wechatProperties;

    /**
     * 会议信人员信息
     */
    private final MeetingParticipantMapper meetingParticipantMapper;

    /**
     * 签到时间相关配置
     */
    private final CheckinProperties checkinProperties;

    public WechatLoginServiceImpl(WechatProperties wechatProperties, MeetingParticipantMapper meetingParticipantMapper,
            CheckinProperties checkinProperties) {
        this.wechatProperties = wechatProperties;
        this.meetingParticipantMapper = meetingParticipantMapper;
        this.checkinProperties = checkinProperties;
    }

    @Override
    public CheckinUserDTO loginWechat(HttpServletRequest request, HttpServletResponse response, String code,
            String meetingId) {
        System.out.println("code:" + code);
        CheckinUserDTO userDTO = new CheckinUserDTO();
        if("aaa".equals(code)) {
            userDTO.setUserId("4751de4209704b4c9d09b67cebaaed78");
            return userDTO;
        }

        // 首先判断是否存session信息
        if (CheckinRequestUtils.getUserFromRequestAttributes().isPresent()) {
            userDTO.setUserId(CheckinRequestUtils.getUserFromRequestAttributes().get().getOperatorId());
        }
        //首先利用token 获取用户的access_token
        String tokenUrl = wechatProperties.getTokenUrl() + "?appid=" + wechatProperties.getAppId() + "&secret="
                + wechatProperties.getAppSecret() + "&code=" + code + "&grant_type=authorization_code";
        // 获取用户的信息
        try {
            System.out.println("tokenUrl:" + tokenUrl);
            JSONObject tokenResult = JSON.parseObject(HttpUtil.get(tokenUrl, "", null));
            System.out.println("tokenResult:" + tokenResult);
            if (tokenResult == null || !tokenResult.containsKey("openid")) {
                log.error("code[{}]获取微信授权信息结果为空", code);
                throw new BaseException(LOGIN_ERROR);
            }

            String openId = tokenResult.getString("openid");
            // 此时需要判断该用户这次会议是否已经登记过
            String userId = meetingParticipantMapper.queryParticipantByOpenId(openId, meetingId);
            if (Strings.isNotBlank(userId)) {
                log.info("已经存在对应的登录记录");
                userDTO.setUserId(userId);
            }
            else {
                // 生成userId和基础记录
                MeetingParticipantDO participantDO = MeetingParticipantDO.builder()
                        .userId(IdUtil.fastSimpleUUID())
                        .meetingId(meetingId)
                        .openId(openId)
                        .build();
                meetingParticipantMapper.insert(participantDO);
                userDTO.setUserId(participantDO.getUserId());
            }

            // 生成用户基础信息,等后续填写后更新信息
            Cookie cookie = new Cookie(CommonConstants.CHECKIN_COOKIE_ID, userDTO.getUserId());
            cookie.setPath(CommonConstants.CHECKIN_COOKIE_PATH);
            cookie.setMaxAge(60 * 60 * 24);
            cookie.setHttpOnly(true);
            String header = request.getHeader(checkinProperties.getXForwardedProto());
            if (CharSequenceUtil.isNotBlank(header) && header.equalsIgnoreCase("https")) {
                cookie.setSecure(true);
            }
            response.addCookie(cookie);
            CheckinRequestUtils.setUserToRequestAttributes(new CheckinUserDTO().setUserId(userId));
            // 进一步获取昵称和头像信息
            try {
                String userInfoUrl = wechatProperties.getQueryCurrentUserUrl() + "?access_token=" + tokenResult.get(
                        "access_token") + "&openid=" + openId + "&lang=zh_CN";
                String userInfoResult = HttpUtil.get(userInfoUrl, "", null);
                log.info("userInfoResult:{}", userInfoResult);
                if (Strings.isNotBlank(userInfoResult)) {
                    JSONObject userInfo = JSON.parseObject(userInfoResult);
                    if (userInfo != null && userInfo.containsKey("nickname") && userInfo.containsKey("headimgurl")) {
                        UpdateWrapper<MeetingParticipantDO> updateWrapper = new UpdateWrapper<>();
                        updateWrapper.eq("user_id", userDTO.getUserId())
                                .set("nickname", userInfo.getString("nickname"))
                                .set("head_img_url", userInfo.getString("headimgurl"));
                        meetingParticipantMapper.update(updateWrapper);
                    }
                }
            }
            catch (Exception e) {
                log.error("获取用户头像信息失败");
            }
        }
        catch (Exception e) {
            log.error("获取微信授权信息失败异常原因:{}", e.getMessage());
            log.error("code[{}]获取微信授权信息失败", code);
            throw new BaseException(LOGIN_ERROR);
        }
        return userDTO;
    }
}
